package io.renren.mqtt;

import com.alibaba.fastjson.JSONObject;

import io.renren.modules.wmstate.dao.WeldingmachineStateDao;

import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.MessageProducer;
import org.springframework.integration.mqtt.core.DefaultMqttPahoClientFactory;
import org.springframework.integration.mqtt.core.MqttPahoClientFactory;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;
import org.springframework.integration.mqtt.support.DefaultPahoMessageConverter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Configuration
@EnableRetry // 启用 Spring 的重试功能
public class CountConfiguration {

    @Autowired
    CountHandler countHandler;

    @Autowired
    WeldingmachineStateDao weldingmachineStateDao;
    static String clientId = UUID.randomUUID().toString();

//    private static final String URL = "tcp://10.142.3.129:1883";
    private static final String URL = "tcp://weld.cmhijs.cn:1883";
    private static final String CLIENT_ID = clientId;

    private static final String TOPIC3 = "/delivery/welstatus/#";

    private static final int MAX_RETRY_ATTEMPTS = 5;
    private int retryCount = 0;

    @Bean
    public MqttConnectOptions mqttConnectOptions(){
        MqttConnectOptions mqttConnectOptions = new MqttConnectOptions();
        mqttConnectOptions.setServerURIs(new String[]{URL});
        mqttConnectOptions.setConnectionTimeout(100);
        mqttConnectOptions.setAutomaticReconnect(true); // 设置自动重连
        mqttConnectOptions.setCleanSession(true);
        return mqttConnectOptions;
    }

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        factory.setConnectionOptions(mqttConnectOptions());
        return factory;
    }


    @Bean
    public MessageChannel mqttInputChannel3() {
        return new DirectChannel();
    }



    @Value("${mqtt.enable}")
    private boolean mqttEnabled; // 通过配置文件注入是否启用 MQTT 订阅的值

    @Bean
    @Retryable(value = {MqttException.class}, maxAttempts = MAX_RETRY_ATTEMPTS, backoff = @Backoff(delay = 5000))
    public MessageProducer inbound3() {
      if (mqttEnabled) {
          CustomMqttPahoMessageDrivenChannelAdapter adapter =
                  new CustomMqttPahoMessageDrivenChannelAdapter(CLIENT_ID + "_3", mqttClientFactory(), TOPIC3);
          adapter.setCompletionTimeout(50000);
          adapter.setConverter(new DefaultPahoMessageConverter());
          adapter.setQos(0);
          adapter.setOutputChannel(mqttInputChannel3());
          return adapter;
      } else {
          return null;
      }
    }


    @Recover
    public void recover(MqttException ex) {
        if (retryCount < MAX_RETRY_ATTEMPTS) {
            log.error("连接到 MQTT 代理失败。正在进行第 " + (retryCount + 1) + " 次重试...", ex);
            retryCount++;
        } else {
            log.error("连接到 MQTT 代理失败，重试次数已达到上限。执行定时任务进行重试或通知相关人员。", ex);
            // 这里您可以执行定时任务进行重试，或者触发通知机制
            // 例如：scheduleRetry();
            scheduleRetry();
        }
    }

    @Scheduled(fixedDelay = 60000) // 每隔一分钟执行一次定时任务
    public void scheduleRetry() {
        if (retryCount >= MAX_RETRY_ATTEMPTS) {
            // 在定时任务中进行重试或者执行通知机制
            log.info("执行定时任务进行 MQTT 连接重试...");
            // 重置重试计数器
            retryCount = 0;
            // 进行新的连接尝试，您可以调用相关方法重新尝试连接
            // retryConnection();
        }
    }

    //定义一个Map存储数据
    private Map<String,Integer> dataMap = new HashMap<>();

    //将Map中的数据存储到数据库中，每5秒存一次
//    @Async("screenTaskExecutor")
    @Scheduled(cron = "0/5 * * * * ?")
    public void saveDataToDB(){
//        log.info("焊机状态线程-" + Thread.currentThread().getId() + "正在执行");
        //遍历Map,如果为空则不执行
        if (dataMap.isEmpty()){
            return;
        }
        for (Map.Entry<String, Integer> entry : dataMap.entrySet()) {
            //获取key
            String wmNo = entry.getKey();
            //获取value
            Integer status = entry.getValue();
            //根据key更新数据库countststus中的status
             weldingmachineStateDao.updateStatusByWmNo(wmNo,status);
        }
    }



    @ServiceActivator(inputChannel = "mqttInputChannel3")
    public void handleMessage2(Message<?> message) throws Exception {
        String msg = (String) message.getPayload();


        JSONObject jsonObject = JSONObject.parseObject(msg);
        String wmNo = jsonObject.getString("wmNo");

       // int gatew = jsonObject.getIntValue("gatew");

        int status = jsonObject.getIntValue("status");

        //更新或者添加数据
        dataMap.put(wmNo,status);


//        countHandler.updateCounts(wmNo,status);
//
//        String countJson = countHandler.sendCountToClient();

        //更新焊机状态信息
        countHandler.sendMessage(msg);
//        countHandler.sendCountToClient();
    }



}